package com.tn.installer.xml;

import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.namespace.NamespaceContext;

/**
 *
 */
public class PrettyPrintXMLStreamWriter implements XMLStreamWriter
{
  private static final String INDENT = "  ";

  private int depth;
  private XMLStreamWriter writer;

  /**
   * Creates a new <code>PrettyPrintXMLStreamWriter</code>.
   */
  public PrettyPrintXMLStreamWriter(XMLStreamWriter writer)
  {
    this.writer = writer;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartElement(String localName) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeStartElement(localName);
    depth++;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeStartElement(namespaceURI, localName);
    depth++;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeStartElement(prefix, localName, namespaceURI);
    depth++;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeEmptyElement(namespaceURI, localName);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeEmptyElement(prefix, localName, namespaceURI);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEmptyElement(String localName) throws XMLStreamException
  {
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeEmptyElement(localName);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEndElement() throws XMLStreamException
  {
    depth--;
    writer.writeCharacters("\n");
    writer.writeCharacters(indent(depth));
    writer.writeEndElement();        
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEndDocument() throws XMLStreamException
  {
    writer.writeEndDocument();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void close() throws XMLStreamException
  {
    writer.close();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void flush() throws XMLStreamException
  {
    writer.flush();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeAttribute(String localName, String value) throws XMLStreamException
  {
    writer.writeAttribute(localName, value);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException
  {
    writer.writeAttribute(prefix, namespaceURI, localName, value);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException
  {
    writer.writeAttribute(namespaceURI, localName, value);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException
  {
    writer.writeNamespace(prefix, namespaceURI);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException
  {
    writer.writeDefaultNamespace(namespaceURI);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeComment(String data) throws XMLStreamException
  {
    writer.writeCharacters("\n\n");
    writer.writeCharacters(indent(depth));
    writer.writeComment(data);
    writer.writeCharacters("\n");
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeProcessingInstruction(String target) throws XMLStreamException
  {
    writer.writeProcessingInstruction(target);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeProcessingInstruction(String target, String data) throws XMLStreamException
  {
    writer.writeProcessingInstruction(target, data);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeCData(String data) throws XMLStreamException
  {
    writer.writeCData(data);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeDTD(String dtd) throws XMLStreamException
  {
    writer.writeDTD(dtd);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeEntityRef(String name) throws XMLStreamException
  {
    writer.writeEntityRef(name);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartDocument() throws XMLStreamException
  {
    writer.writeStartDocument();
    writer.writeCharacters("\n\n");
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartDocument(String version) throws XMLStreamException
  {
    writer.writeStartDocument(version);
    writer.writeCharacters("\n");
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeStartDocument(String encoding, String version) throws XMLStreamException
  {
    writer.writeStartDocument(encoding, version);
    writer.writeCharacters("\n");
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeCharacters(String text) throws XMLStreamException
  {
    writer.writeCharacters(text);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void writeCharacters(char[] text, int start, int len) throws XMLStreamException
  {
    writer.writeCharacters(text, start, len);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getPrefix(String uri) throws XMLStreamException
  {
    return writer.getPrefix(uri);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setPrefix(String prefix, String uri) throws XMLStreamException
  {
    writer.setPrefix(prefix, uri);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setDefaultNamespace(String uri) throws XMLStreamException
  {
    writer.setDefaultNamespace(uri);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setNamespaceContext(NamespaceContext context) throws XMLStreamException
  {
    writer.setNamespaceContext(context);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public NamespaceContext getNamespaceContext()
  {
    return writer.getNamespaceContext();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Object getProperty(String name) throws IllegalArgumentException
  {
    return writer.getProperty(name);
  }

  /**
   * Returns an indent <code>String</code> for the specified <code>depth</code>.
   */
  private String indent(int depth)
  {
    StringBuffer indent = new StringBuffer();

    while (indent.length() < INDENT.length() * depth)
    {
      indent.append(INDENT);
    }

    return indent.toString();
  }
}
